<script lang="ts">
    import { onDestroy } from "svelte";
    import { clamp } from "./utils";
    import { useStyle } from "../utils/useStyle";

    const props = $props();
    let container: any;
    const handleMouseDown = (e: any) => {
        if (typeof e.button === "number" && e.button !== 0) return false;
        handleChange(e);

        document.addEventListener("mousemove", handleChange, false);
        document.addEventListener("mouseup", onDragEnd, false);
    };

    const onDragEnd = (e: any) => {
        handleChange(e);
        document.removeEventListener("mousemove", handleChange);
        document.removeEventListener("mouseup", onDragEnd);
    };

    onDestroy(() => {
        document.removeEventListener("mousemove", handleChange);
        document.removeEventListener("mouseup", onDragEnd);
    });

    const handleChange = (e: any) => {
        e.preventDefault();
        e.stopPropagation();

        const { clientWidth, clientHeight } = container;
        const xOffset = container.getBoundingClientRect().left + window.pageXOffset;
        const yOffset = container.getBoundingClientRect().top + window.pageYOffset;
        const left = clamp(e.pageX - xOffset, 0, clientWidth);
        const top = clamp(e.pageY - yOffset, 0, clientHeight);
        const saturation = left / clientWidth;
        const bright = clamp(1 - top / clientHeight, 0, 1);

        props.onChange?.({
            h: props.value.hsv.h,
            s: saturation,
            v: bright,
            a: props.value.hsv.a,
            source: "hsva",
        });
    };

    const bgColorStyle = $derived(useStyle({}, { background: `hsl(${props.value.hsv.h}, 100%, 50%)` }));
    const pointerStyle = $derived(useStyle({}, { top: `${-(props.value.hsv.v * 100) + 1 + 100}%`, left: `${props.value.hsv.s * 100}%` }));
</script>

<!-- svelte-ignore a11y_no_static_element_interactions -->
<div class="cm-saturation" style={bgColorStyle} onmousedown={handleMouseDown} bind:this={container}>
    <div class="cm-saturation-white"></div>
    <div class="cm-saturation-black"></div>
    <div class="cm-saturation-pointer" style={pointerStyle}>
        <div class="cm-saturation-circle"></div>
    </div>
</div>
